"""
des: 
author: 邵宁
date: 2022-08-17
"""
import glob
import os
import re
import sqlite3
import logging
from flask import Flask, request, redirect, send_file, g
from flask import Blueprint, make_response, jsonify, send_from_directory
from contextlib import closing
import time
import ctypes
import inspect
import requests
import threading
from flask_cors import CORS

logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(message)s', datefmt='%Y/%m/%d %H:%M:%S')

app = Flask(__name__)  # 在当前文件下创建应用


class MsgTemplate:
    def __init__(self):
        pass

    def get_json(self):
        return {}


threads_paperDownloading = {}


def stop_thread(thread):
    def _async_raise(tid, exc_type):
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exc_type):
            exc_type = type(exc_type)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exc_type))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")

    _async_raise(thread.ident, SystemExit)


# username: {thread_id: {"thread_obj": thread_obj, "thread_process": 0, "paper_url": "XXX"}}


def get_file_by_url(paper_url, thread_id, username):
    try:
        with closing(requests.get(paper_url, stream=True)) as response:
            chunk_size = 1024  # 单次请求最大值
            content_size = int(response.headers['content-length'])  # 内容体总大小
            data_count = 0
            data_list = []
            for data in response.iter_content(chunk_size=chunk_size):
                data_list.append(data)
                data_count = data_count + len(data)
                now_jd = (data_count / content_size) * 100
                threads_paperDownloading[username][thread_id]["thread_process"] = int(now_jd)
            # pdf_upload(data_list, username=username, paper_url=paper_url) 下载完成回调函数
    except Exception as e:
        pass
    if thread_id in threads_paperDownloading[username]:
        threads_paperDownloading[username].pop(thread_id)


@app.route('/download_status', methods=['POST'])
def download_status():
    # print(threads_paperDownloading)
    user_token = request.json.get('user_token', '')
    state_all = []
    for thread_id, thread_one in threads_paperDownloading.get(user_token, {}).items():
        state_all.append({"thread_id": thread_id, "paper_url": thread_one["paper_url"],
                          "thread_process": thread_one["thread_process"]})
    process = {"thread_all": state_all}
    return process


@app.route('/download_stop', methods=['POST'])
def download_stop():
    user_token = request.json.get('user_token', '')
    thread_id = request.json.get('thread_id', '')
    stop_thread(threads_paperDownloading[user_token][thread_id]["thread_obj"])
    # self.write("任务已终止")


@app.route('/download_start', methods=['POST'])
def download_start():
    user_token = request.json.get('user_token', '')
    download_url = request.json.get('download_url', '')
    thread_id = "t_" + time.strftime("%Y%m%d_%H%M%S")
    thread_download = threading.Thread(target=get_file_by_url, args=(download_url, thread_id, user_token))
    thread_download.start()
    if user_token not in threads_paperDownloading:
        threads_paperDownloading[user_token] = {}
    threads_paperDownloading[user_token][thread_id] = {"thread_obj": thread_download, "thread_process": 0,
                                                       "download_url": download_url}


@app.route("/")  # 装饰器，url，路由
def index():  # 试图函数
    return redirect("/static/index.html")


@app.route('/download_start', methods=['POST'])
def download_start():
    user_token = request.json.get('user_token', '')
    msg = MsgTemplate()
    return msg.get_json()


CORS(app, resources=r'/*')
if __name__ == "__main__":
    app.run(debug=True, port=8092)  # 运行app
